Rails World 2024 tickets on April 30, legacy index name format for Rails 7.0, etc | This Week in Rails
日本標準時では5月1日の深夜2時からです
ActiveRecordに関する変更です
migrationでテーブルの名称を変更したいとき、rename_tableメソッドが使えます
rename_tableが実行されると、indexの名前もrenameされます
code:rb
create_table :posts do |t|
t.string :title
t.index :title
end
ActiveRecord::Base.connection.indexes(:posts).first.name
# => "index_posts_on_title"
long_table_name = "a" * 60
rename_table :posts, long_table_name
ActiveRecord::Base.connection.indexes(long_table_name).first.name
# => "index_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_on_title"
rails 7.1でindexの名前のフォーマットが変わりました
具体的には index 名が bytesize 63以上の場合にはindexの名称を短縮版でつくるようになりました
code:rb
def generate_index_name(table_name, column)
name = "index_#{table_name}_on_#{Array(column) * '_and_'}"
return name if name.bytesize <= max_index_name_size
# Fallback to short version, add hash to ensure uniqueness
hashed_identifier = "_" + OpenSSL::Digest::SHA256.hexdigest(name).first(10)
name = "idx_on_#{Array(column) * '_'}"
short_limit = max_index_name_size - hashed_identifier.bytesize
short_name = name.mb_chars.limit(short_limit).to_s
"#{short_name}#{hashed_identifier}"
end
そうだったんだ、これは普通に便利だな、長いindex名称に困らされたことが何回かあるわ
"idx_on_title#{hashed_identifier}"
現状は Migrationで ActiveRecord::Migration[7.0] を使っていても、indexのrenameはv7.1のフォーマットで実施されるようになっています
migrationファイルに rename_table が含まれている場合、v7.0 と v7.1 の間で作成されたインデックス名が異なる可能性があります
この場合、どんなデメリットがあるでしょうか
複数の開発者がローカルで環境を作った際に v7.0 のときから環境を作っていたエンジニアと、v7.1以降に環境を作ったエンジニアとの差が出てしまう
既存のRailsアプリケーションに対してマルチDBの構成をつくる際に、2つ目に作ったDBのindex名が1つ目のDBと異なってしまう
今回のプルリクエストでは、7.0以前のmigrationファイルでは旧フォーマットでindex名が定まるように修正しています
ActiveSupportに関する変更です
このプルリクエストでは、XML に hexBinary パーサーを追加しています
hexBinary は、XML のプリミティブ データ型の 1 つです